#ifndef MAINDIALOG_H
#define MAINDIALOG_H

#include <QDialog>

#include <QButtonGroup>
#include <QDebug>
#include <QHBoxLayout>
#include <QHostAddress>
#include <QKeyEvent>
#include <QLabel>
#include <QMessageBox>
#include <QProcess>
#include <QSettings>
#include <QTcpSocket>
#include <QTextCodec>
#include <QTimer>
#include <QVBoxLayout>

#include "logdialog.h"
#include "relaybutton.h"
#include "relayevent.h"
#include "qextserialport.h"
#include "qextserialenumerator.h"

#define SETTINGS_FILENAME   (QApplication::applicationDirPath() + "/ini/Settings.ini")
#define LOGMSG_FILENAME     (QApplication::applicationDirPath() + "/log/LogMsg.log")

#define NUM_ALARM_DEF   1

#define NUM_RELAY_MAX   10
#define NUM_RELAY_DEF   5

#define NUM_BOARD_DEF   1

struct AlarmData
{
    qint32      bid;    // read onley
    qint32      rid;    // read onley
    qint32      id;     // read onley

    qint32      hour;
    qint32      minute;
    qint32      action;     // 0(OFF), 1(ON)
    qint32      dayOfWeek;  // 0(sun), ..., sat(6)
};
struct ShutDownData
{
    qint32      type;   // 0(Windows), 1(Linux), ...
    QString     ipOrName;
    QString     user;
    QString     password;
};
struct RelayData
{
    qint32      bid;    // read onley
    qint32      id;     // read onley

    QString     name;
    qint32      notUsed;
    qint32      status;
    qint32      pushDelay;  // [sec]
    quint32     saveTime;   // [sec]

    QList<ShutDownData> shutDowns;
    QList<AlarmData> alarms;
};
struct BoardData
{
    qint32      id;     // read onley

    QString     name;
    qint32      normalClose;

    QList<RelayData> relays;
};

#define PACKET_STARTEND         0x7E
#define PACKET_MIN_LEN          0x06
#define PACKET_CMD_BDINIT       0x00
#define PACKET_CMD_SET          0x02
#define PACKET_CMD_GET          0x03
#define PACKET_CMD_NACK         0xEE

#define RELAY_STATUS_OFF        0x00
#define RELAY_STATUS_ON         0x01
#define RELAY_STATUS_PENDING    0x10
#define RELAY_STATUS_SHUTDOWN   0x20
#define RELAY_STATUS_UNKNOWN    0x40
#define RELAY_STATUS_NOTUSED    0x80

struct PacketData
{
    qint32      sendCount;
    QTime       sendTime;
    QByteArray  dataBuf;
};


namespace Ui {
class MainDialog;
}

class MainDialog : public QDialog
{
    Q_OBJECT
    
public:
    explicit MainDialog(QWidget *parent = 0);
    ~MainDialog();

    int shutDownDelay();

public slots:
    void argsMessage(const QString& message);

protected:
    virtual void keyPressEvent(QKeyEvent *e);
    virtual void timerEvent(QTimerEvent *e);
    virtual void customEvent(QEvent *e);

Q_SIGNALS:
    void signalNeedToShow();
    void signalMsg(const QString msg);
    void signalSave(const QString fileName);

private:
    void loadSettings();
    void saveSettings();

    void initLogDialog();
    void exitLogDialog();

    void initWidgets();

    void add(PacketData &packetData, bool noSend=false);

    void initServer();
    void updateStatueServer(int bid, int rid, int status);
    void updatePowerServer(int savePerHour, quint32 saveTimeMinute, float saveKWH);

    quint32 updateSaveTime();

    enum {
        IdButtonSerialPort = 1000, IdButtonTest, IdButtonExit,
        IdButtonRelay = 2000, IdButtonRelayMax = 2999,
    };

private Q_SLOTS:
    void onButtonClicked(int id);
    void onSerialOpen();
    void onSerialSend();
    void onSerialRead();
    void onSerialPortAddedOrRemoved(QextPortInfo portInfo);
    void onTcpConnect();
    void onTcpConnected();
    void onTcpRead();
    void onTcpConnectionClosedByServer();
    void onTcpError(QAbstractSocket::SocketError socketError);
    void onMinuteProc();

    void onTestTimer();
    
private:
    Ui::MainDialog *ui;

    int m_tidOneSecond;

    LogDialog *m_pLogDialog;
    QButtonGroup *m_pButtonGroup;

    QString m_setupDateTime;
    int m_savePerHour;
    float m_saveKWH;
    int m_shutDownDelay;
    int m_testCount;

    QString m_portName;
    PortSettings m_portSettings;
    int m_numRetry;
    int m_msecRetry;

    QHostAddress m_hostAddress;
    int m_hostPort;

    QString m_ctrlName;
    int m_ctrlDayOfWeek[7];   // Sun(0) ~ Sat(6)

    QList<BoardData> m_BoardDatas;

    QextSerialPort *m_pSerialPort;
    QextSerialEnumerator *m_pSerialEnumerator;
    QByteArray m_recvBuf;
    QList<PacketData> m_listSendPacket;
    int m_tidSendPacket;

    QTcpSocket *m_pTcpSoceket;

    int m_nTestCount;
    QTimer *m_testTimer;
};

#endif // MAINDIALOG_H
